对flask背后运行机制感兴趣,参考网上资料,结合源码分析run函数运行时的机制,主要整理出函数调用栈。以flask0.1分析
首先
Flask官方文档经典示例 hello.py
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run()
现在来分析app.run()启动时发生了什么? # 代码只列出用到的函数,去掉注释等
flask.py
class Flask(object):
def run(self, host='localhost', port=5000, **options):
from werkzeug import run_simple
if 'debug' in options:
self.debug = options.pop('debug')
options.setdefault('use_reloader', self.debug)
options.setdefault('use_debugger', self.debug)
return run_simple(host, port, self, **options)
run函数导入from werkzeug import run_simple 运行run_simple(host, port, self, **options)
werkzeug/serving.py
def run_simple(hostname, port, application, use_reloader=False, extra_files=None, threaded=False, processes=1):
def inner():
srv = make_server(hostname, port, application, threaded,
processes)
try:
srv.serve_forever()
except KeyboardInterrupt:
pass
inner()
run_simple函数主要运行inner(),inner调用make_server()返回类,然后调用返回类的serve_forever()。先来看看make_server()
werkzeug/serving.py
ddef make_server(host, port, app=None, threaded=False, processes=1):
if threaded and processes > 1:
raise ValueError("cannot have a multithreaded and "
"multi process server.")
elif threaded:
class handler(BaseRequestHandler):
multithreaded = True
class server(ThreadingMixIn, WSGIServer):
pass
elif processes > 1:
class handler(BaseRequestHandler):
multiprocess = True
max_children = processes - 1
class server(ForkingMixIn, WSGIServer):
pass
else:
handler = BaseRequestHandler
server = WSGIServer
srv = server((host, port), handler)
srv.set_app(app)
return srv
make_server(hostname, port, application, threaded, processes) 传入的都是默认参数,起作用的代码是
else:
handler = BaseRequestHandler
server = WSGIServer
srv = server((host, port), handler)
srv.set_app(app)
return srv
可以看出srv = server((host, port), handler) ,其实就是srv = WSGIServer((host, port), BaseRequestHandler),返回类就是WSGIServer ,绑定BaseRequestHandler。先看WSGIServer
wsgiref/simple_server.py
class WSGIServer(HTTPServer):
def __init__= 标准库 BaseHTTPServer.py class HTTPServer(SocketServer.TCPServer) : #WSGIServer继承HTTPServer的__init__函数,它自己没有 ,这句是我加的方便理解 ,下同
def set_app(self,application): #这个就是make_server函数中调用的 set_app
self.application = application
def get_app(self): #
return self.application
标准库 BaseHTTPServer.py
class HTTPServer(SocketServer.TCPServer)
def __init__= 标准库 SocketServer.py class TCPServer(BaseServer):
标准库 SocketServer.py
class TCPServer(BaseServer):
def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True):
BaseServer.__init__(self, server_address, RequestHandlerClass)
self.socket = socket.socket(self.address_family,
self.socket_type)
if bind_and_activate: # 这里调用socket.socket绑定端口
try:
self.server_bind()
self.server_activate()
except:
self.server_close()
raise
class BaseServer:
def __init__(self, server_address, RequestHandlerClass):
self.server_address = server_address
self.RequestHandlerClass = RequestHandlerClass
self.__is_shut_down = threading.Event()
self.__shutdown_request = False
def serve_forever(self, poll_interval=0.5): #这个就是run_simple中调用的serve_forever
self.__is_shut_down.clear()
try:
while not self.__shutdown_request:
r, w, e = _eintr_retry(select.select, [self], [], [],
poll_interval)
if self in r:
self._handle_request_noblock() #调用serve_forever时调用_handle_request_noblock
finally:
self.__shutdown_request = False
self.__is_shut_down.set()
def _handle_request_noblock(self):
try:
request, client_address = self.get_request()
except socket.error:
return
if self.verify_request(request, client_address):
try:
self.process_request(request, client_address) #继续
except:
self.handle_error(request, client_address)
self.shutdown_request(request)
def process_request(self, request, client_address):
self.finish_request(request, client_address) #继续
self.shutdown_request(request)
def finish_request(self, request, client_address):
self.RequestHandlerClass(request, client_address, self) # #继续 并参见 werkzeug/serving.py make_server()
调用serve_forever后到了self.RequestHandlerClass(request, client_address, self) ,根据前面的代码可知RequestHandlerClass 就是werkzeug/serving.py中的BaseRequestHandler,继续
class BaseRequestHandler(WSGIRequestHandler):
def __init__= 标准库 wsgiref/simple_server.py class WSGIRequestHandler(BaseHTTPRequestHandler): #这句跟前面一样继承父类
wsgiref/simple_server.py
class WSGIRequestHandler(BaseHTTPRequestHandler):
def __init__= 标准库 BaseHTTPServer.py class BaseHTTPRequestHandler(SocketServer.StreamRequestHandler): #继续父类
BaseHTTPServer.py
class BaseHTTPRequestHandler(SocketServer.StreamRequestHandler):
def __init__= 标准库 SocketServer.py class StreamRequestHandler(BaseRequestHandler): #继续父类
SocketServer.py
class StreamRequestHandler(BaseRequestHandler):
#继续父类
class BaseRequestHandler:
def __init__(self, request, client_address, server):
self.request = request
self.client_address = client_address
self.server = server
self.setup()
try:
self.handle() # 运行 参见 werkzeug/serving.py class BaseRequestHandler.handle
finally:
self.finish()
最后运行了self.handle() 参见 werkzeug/serving.py class BaseRequestHandler.handle
前面有,再贴下看看
class BaseRequestHandler(WSGIRequestHandler):
def handle(self): #1、调用的就是这个handle,覆盖了父类的handle
self.raw_requestline = self.rfile.readline()
if self.parse_request():
self.get_handler().run(self.server.get_app()) #2、调用 get_handler()后,还继续调用 run() ,get_app就是wsgiref/simple_server.py中WSGIServer类定义的函数
def get_handler(self): # 3、看看它返回了什么
handler = self._handler_class
if handler is None:
class handler(ServerHandler): #4、新建一个类 返回的就是这个类 ,继承ServerHandler
'''
5、直接从其他文件copy出所需代码,也就是handler的父类
wsgiref/simple_server.py class ServerHandler(SimpleHandler): 继续父类
wsgiref/handlers.py
class SimpleHandler(BaseHandler):
def __init__(self,stdin,stdout,stderr,environ,multithread=True, multiprocess=False ):
self.stdin = stdin
self.stdout = stdout
self.stderr = stderr
self.base_env = environ
self.wsgi_multithread = multithread
self.wsgi_multiprocess = multiprocess
class BaseHandler: #6、调用的就是这个类的run函数
def run(self, application):
try:
self.setup_environ()
self.result = application(self.environ, self.start_response) #7、调用app,也就是app=Flask() Flask类的 __call__
self.finish_response()
except:
try:
self.handle_error()
except:
# If we get an error handling an error, just give up already!
self.close()
raise # ...and let the actual server figure it out.
'''
wsgi_multithread = self.multithreaded
wsgi_multiprocess = self.multiprocess
self._handler_class = handler
rv = handler(self.rfile, self.wfile, self.get_stderr(),
self.get_environ())
rv.request_handler = self
return rv
可以看出最后调用的是application(self.environ, self.start_response) 这个application就是开始的app = Flask(__name__),调用类就是调用类的__call__ 函数 ,继续贴一下源码
class Flask(object):
def __call__(self, environ, start_response):
return self.wsgi_app(environ, start_response)
def wsgi_app(self, environ, start_response):
with self.request_context(environ):
rv = self.preprocess_request()
if rv is None:
rv = self.dispatch_request()
response = self.make_response(rv)
response = self.process_response(response)
return response(environ, start_response)
OK,大功告成,最后调用wsgi_app(self, environ, start_response)函数,这个就是返回响应的主函数了!!
从整个流程中,flask利用WSGIServer类启动监听端口并绑定,BaseRequestHandler类接收、返回相应的信息!完全符合WSGI要求。
剩余的工作就太过于底层,不好深入分析了。也画了调用流程图,不过太大不好传,如果有需要可以继续交流!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。